import asyncio
import json
from concurrent.futures import ThreadPoolExecutor
from flask import Flask, request
from weworkapi.callback.WXBizMsgCrypt import WXBizMsgCrypt
import xml.etree.cElementTree as ET
from weworkapi.api.CorpApi import CorpApi
import ai

'''
请求方式：GET
请求地址：http://xxx:8080/kf/?msg_signature=ASDFQWEXZCVAQFASDFASDFSS&timestamp=13500001234&nonce=123412323&echostr=ENCRYPT_STR
参数说明

参数	必须	说明
msg_signature	是	企业微信加密签名，msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
timestamp	是	时间戳
nonce	是	随机数
echostr	是	加密的字符串。需要解密得到消息内容明文，解密后有random、msg_len、msg、CorpID四个字段，其中msg即为消息内容明文
企业后台收到请求后，需要做如下操作：

对收到的请求做Urldecode处理
通过参数msg_signature对请求进行校验，确认调用者的合法性。
解密echostr参数得到消息内容(即msg字段)
在1秒内原样返回明文消息内容(不能加引号，不能带bom头，不能带换行符)
'''
TOKEN = "xLy31qd"  # 假设token为固定值，实际应从配置中读取
ENCODING_AES_KEY = "xxxxxxxxxxxxxxx" # 应用密钥
CORP_ID = "xxxxxx"  # 企业ID
AGETNT_ID = "1000003"
APP_SECRET = "xxxxxxxxxxxxxxxxxxx"  # 应用密钥

GBS_OPEN_KFID = 'xxxxxxxxxxxxxxxxx' # 客服号

# 创建Flask应用实例
app = Flask(__name__)

corpApi = CorpApi(CORP_ID, APP_SECRET, TOKEN)

wxcpt = WXBizMsgCrypt(TOKEN, ENCODING_AES_KEY, CORP_ID)


@app.route('/kf', methods=['GET'])
def kf_handler_get():
    """
    处理GET请求并返回解密后的消息内容
    """
    # 获取请求参数
    msg_signature = request.args.get('msg_signature')
    timestamp = request.args.get('timestamp')
    nonce = request.args.get('nonce')
    echostr = request.args.get('echostr')

    ret, sEchoStr = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr)
    if (ret != 0):
        print("ERR: VerifyURL ret: " + str(ret))
        return "VerifyURL ret: " + str(ret)
    else:
        print("done VerifyURL")
        # 验证URL成功，将sEchoStr返回给企业号
        return sEchoStr

async def send_chat_message_dify(external_userid, open_kfid, msg_id, msg):
    ai_reponse = ai.send_chat_message_dify(msg, external_userid)
    print(f"dify ai_reponse: {ai_reponse}")
    # 去掉ai_reponse回车换行符
    ai_reponse = ai_reponse.replace("<think>", "").replace("</think>", "").strip()
    corpApi.send_msg_text(external_userid, open_kfid, msg_id, ai_reponse)


@app.route('/kf', methods=['POST'])
def kf_handler_post():
    """
    处理POST请求并返回解密后的消息内容
    """
    # 获取URL参数
    sReqMsgSig = request.args.get('msg_signature')
    sReqTimeStamp = request.args.get('timestamp')
    sReqNonce = request.args.get('nonce')

    # 获取请求体数据
    sReqData = request.data.decode('utf-8')

    # 打印接收到的报文数据
    print(f"Received kf POST request with parameters:")
    print(f"msg_signature: {sReqMsgSig}")
    print(f"timestamp: {sReqTimeStamp}")
    print(f"nonce: {sReqNonce}")
    print(f"post_data: {sReqData}")
    ret, sMsg = wxcpt.DecryptMsg(sReqData, sReqMsgSig, sReqTimeStamp, sReqNonce)
    print(ret, sMsg)
    if (ret != 0):
        print("ERR: DecryptMsg ret: " + str(ret))
        return "DecryptMsg ret: " + str(ret)
    # 解密成功，sMsg即为xml格式的明文
    # TODO: 对明文的处理
    # For example:
    print(f"sMsg: {sMsg}")
    xml_tree = ET.fromstring(sMsg)
    open_kfid = xml_tree.find("OpenKfId").text
    response = corpApi.sync_msg(None, open_kfid)
    print(response)
    print(f"type: {type(response)}")
    if response['errcode'] == 0:
        external_userid = response['msg_list'][-1]['external_userid']
        msg_id = response['msg_list'][-1]['msgid']
        msgtype = response['msg_list'][-1]['msgtype']
        if msgtype == "text":
            msg = response['msg_list'][-1]['text']['content']

            if open_kfid == GBS_OPEN_KFID:
                # 使用 run_in_executor 提交任务到线程池
                loop = asyncio.new_event_loop()
                asyncio.set_event_loop(loop)
                loop.run_in_executor(ThreadPoolExecutor(), asyncio.run,
                                     send_chat_message_dify(external_userid, open_kfid, msg_id, msg))
                return "success"
    return "success"


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8100, debug=False)
